package com.bkgy.controller.repTcmThickWidth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bkgy.controller.repTcmThickWidth.entity.RepTcmThickWidth;
import com.bkgy.controller.repTcmThickWidth.entity.pdo.ClientSteelGradeThickWidthRes;
import com.bkgy.controller.repTcmThickWidth.entity.pdo.SteelGradeThickWidthRes;
import com.bkgy.controller.repTcmThickWidth.entity.pdo.TcmSteelGradeOutput;
import com.bkgy.controller.repTcmThickWidth.mapper.IRepTcmThickWidthMapper;
import com.bkgy.controller.repTcmThickWidth.service.IRepTcmThickWidthService;
import com.bkgy.sys.common.entity.ResultData;
import com.bkgy.util.DateUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Service
@RequiredArgsConstructor
public class RepTcmThickWidthServiceImpl extends ServiceImpl<IRepTcmThickWidthMapper, RepTcmThickWidth> implements IRepTcmThickWidthService {
    private final IRepTcmThickWidthMapper mapper;

    @Override
    public ResultData<SteelGradeThickWidthRes> steelRep(String beginDate, String endDate) {
        List<RepTcmThickWidth> list = new ArrayList<>();
        if (beginDate.length() == 8) {
            //查询的是完整1天，从提前算好的结果中查询
            LambdaQueryWrapper<RepTcmThickWidth> w = new LambdaQueryWrapper<>();
            w.ge(RepTcmThickWidth::getShijian, beginDate).le(RepTcmThickWidth::getShijian, endDate)
                    .orderByAsc(RepTcmThickWidth::getSteelgrade).orderByAsc(RepTcmThickWidth::getThickType);
            list = list(w);
        } else {
            list = loadRangData(beginDate, endDate);
        }

        List<SteelGradeThickWidthRes> resList = new ArrayList<>();
        for (RepTcmThickWidth repTcmThickWidth : list) {
            SteelGradeThickWidthRes res = new SteelGradeThickWidthRes();
            BeanUtils.copyProperties(repTcmThickWidth, res);
            resList.add(res);
        }
        return ResultData.ResultDataSuccess(resList, resList.size());
    }

    @Override
    public ResultData<ClientSteelGradeThickWidthRes> clientSteelRep(String beginDate, String endDate) {
        List<RepTcmThickWidth> list = new ArrayList<>();
        if (beginDate.length() == 8) {
            LambdaQueryWrapper<RepTcmThickWidth> w = new LambdaQueryWrapper<>();
            w.ge(RepTcmThickWidth::getShijian, beginDate).le(RepTcmThickWidth::getShijian, endDate)
                    .orderByAsc(RepTcmThickWidth::getClientName).orderByAsc(RepTcmThickWidth::getSteelgrade).orderByAsc(RepTcmThickWidth::getThickType);
            list = list(w);
        } else {
            list = loadRangData(beginDate, endDate);
        }

        List<ClientSteelGradeThickWidthRes> resList = new ArrayList<>();
        for (RepTcmThickWidth repTcmThickWidth : list) {
            if (isShow(repTcmThickWidth.getClientName())) {
                ClientSteelGradeThickWidthRes res = new ClientSteelGradeThickWidthRes();
                BeanUtils.copyProperties(repTcmThickWidth, res);
                resList.add(res);
            }
        }
        return ResultData.ResultDataSuccess(resList, resList.size());
    }

    private boolean isShow(String clientName) {
        boolean flag = false;
        String[] arr = new String[]{"比亚迪", "上汽乘用车", "吉利汽车", "零跑汽车", "东风日产",
                "江铃汽车", "长城汽车", "陕汽", "一汽集团", "广汽埃安",
                "河北长安", "奇瑞汽车", "广汽传祺汽车有限公司", "现代汽车", "宝马",
                "奔驰"};
        for (String s : arr) {
            if (s.equals(clientName)) {
                flag = true;
                break;
            }
        }
        return flag;
    }

    @Override
    public ResultData<String> buildSteelGradeWidthThickJob(Date d) {
        String beginDate = DateUtil.getDateToString(d, "yyyyMMdd");
        String endDate = DateUtil.getDateToString(DateUtil.getNextDayZero(d), "yyyyMMdd");

        List<RepTcmThickWidth> resList = loadRangData(beginDate, endDate);
        saveBatch(resList);
        return ResultData.ResultDataSuccess("SUCCESS");
    }

    private List<RepTcmThickWidth> loadRangData(String beginDate, String endDate) {
        List<TcmSteelGradeOutput> dbDataList = mapper.selectTcmPdoL3(beginDate, endDate);

        //按钢种分组数据
        Map<String, List<TcmSteelGradeOutput>> steelMap = new HashMap<>();
        for (TcmSteelGradeOutput dbData : dbDataList) {
            String steelGrade = dbData.getSteelgrade();
            if (!steelMap.containsKey(steelGrade)) {
                List<TcmSteelGradeOutput> l = new ArrayList<>();
                l.add(dbData);
                steelMap.put(steelGrade, l);
            } else {
                steelMap.get(steelGrade).add(dbData);
            }
        }

        List<RepTcmThickWidth> resList = new ArrayList<>();
        //分钢种统计
        for (Map.Entry<String, List<TcmSteelGradeOutput>> entry : steelMap.entrySet()) {
            Map<String, RepTcmThickWidth> thickMap = new HashMap<>();
            String steelGrade = entry.getKey();
            List<TcmSteelGradeOutput> list = entry.getValue();
            for (TcmSteelGradeOutput dbData : list) {
                //按厚度分类
                BigDecimal outMatActThick = dbData.getOutMatActThick();
                String thickKey = getThickRangeKey(outMatActThick);
                BigDecimal width = dbData.getOutMatActWidth();
                String range = getWidthRange(width);
                BigDecimal outMatWt = dbData.getOutMatWt();
                Integer duration = dbData.getDuration();
                if (!thickMap.containsKey(thickKey)) {
                    RepTcmThickWidth rep = new RepTcmThickWidth();
                    rep.setShijian(beginDate);
                    rep.setSteelgrade(steelGrade);
                    rep.setThickType(thickKey);
                    rep.setClientName(dbData.getClientName());
                    try {
                        rep.getClass().getMethod("setWidth" + range + "OutputWt", BigDecimal.class).invoke(rep, outMatWt);
                        //将生产分钟数临时存到卷数里
                        rep.getClass().getMethod("setWidth" + range + "OutmatRoll", Integer.class).invoke(rep, duration);
                        //将卷数暂存到小时产量字段上
                        rep.getClass().getMethod("setWidth" + range + "OutmatHour", BigDecimal.class).invoke(rep, BigDecimal.ONE);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    thickMap.put(thickKey, rep);
                } else {
                    RepTcmThickWidth rep = thickMap.get(thickKey);
                    try {
                        BigDecimal oldOutMatWt = (BigDecimal) rep.getClass().getMethod("getWidth" + range + "OutputWt").invoke(rep);
                        BigDecimal oldOutMatWtHour = (BigDecimal) rep.getClass().getMethod("getWidth" + range + "OutmatHour").invoke(rep);
                        Integer oldDuration = (Integer) rep.getClass().getMethod("getWidth" + range + "OutmatRoll").invoke(rep);
                        rep.getClass().getMethod("setWidth" + range + "OutputWt", BigDecimal.class).invoke(rep, outMatWt.add(oldOutMatWt));
                        rep.getClass().getMethod("setWidth" + range + "OutmatRoll", Integer.class).invoke(rep, duration + oldDuration);
                        rep.getClass().getMethod("setWidth" + range + "OutmatHour", BigDecimal.class).invoke(rep, oldOutMatWtHour.add(BigDecimal.ONE));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            //计算不同厚度的小时产量、卷数
            for (Map.Entry<String, RepTcmThickWidth> entry1 : thickMap.entrySet()) {
                RepTcmThickWidth rep = entry1.getValue();
                //小时产量
                try {
                    //5个宽度档位区间
                    for (int i = 1; i < 5; i++) {
                        BigDecimal outMatWt = (BigDecimal) rep.getClass().getMethod("getWidth" + i + "OutputWt").invoke(rep);
                        BigDecimal rollNum = (BigDecimal) rep.getClass().getMethod("getWidth" + i + "OutmatHour").invoke(rep);
                        Integer duration = (Integer) rep.getClass().getMethod("getWidth" + i + "OutmatRoll").invoke(rep);
                        if (duration == 0) continue;
                        //小时产量
                        BigDecimal outMatHour = outMatWt.multiply(BigDecimal.valueOf(60)).divide(BigDecimal.valueOf(duration), 2, RoundingMode.HALF_UP);
                        rep.getClass().getMethod("setWidth" + i + "OutmatHour", BigDecimal.class).invoke(rep, outMatHour);
                        rep.getClass().getMethod("setWidth" + i + "OutmatRoll", Integer.class).invoke(rep, rollNum.intValue());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            resList.addAll(thickMap.values());
        }
        return resList;
    }

    private String getThickRangeKey(BigDecimal v) {
        if (v.compareTo(BigDecimal.valueOf(2.5)) > 0) {
            return "(2.5~+∞)";
        } else if (v.compareTo(BigDecimal.valueOf(2)) > 0) {
            return "(2.0~2.5]";
        } else if (v.compareTo(BigDecimal.valueOf(1.5)) > 0) {
            return "(1.5~2.0]";
        } else if (v.compareTo(BigDecimal.valueOf(1.0)) > 0) {
            return "(1.0~1.5]";
        } else if (v.compareTo(BigDecimal.valueOf(0.7)) > 0) {
            return "(0.7~1.0]";
        } else {
            return "(0~0.7]";
        }
    }

    private String getWidthRange(BigDecimal v) {
        if (v.compareTo(BigDecimal.valueOf(1800)) > 0) {
            return "4";
        } else if (v.compareTo(BigDecimal.valueOf(1500)) > 0) {
            return "3";
        } else if (v.compareTo(BigDecimal.valueOf(1200)) > 0) {
            return "2";
        } else {
            return "1";
        }
    }
}
